﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UtilLib
{
    /// <summary>
    /// 扩展
    /// </summary>
    public static partial class Util
    {
        /// <summary>
        /// 获取两个日期之间天数
        /// </summary>
        /// <param name="dtLast">时间一</param>
        /// <param name="dtThis">时间二</param>
        /// <param name="abs">是否取绝对值</param>
        /// <returns></returns>
        public static int IntervalDays(this DateTime dtLast, DateTime dtThis, bool abs = false)
        {
            var result = (dtThis.Date - dtLast.Date).Days;
            return (abs ? Math.Abs(result) : result);
        }
        /// <summary>
        /// 获取间隔时间Ticks
        /// </summary>
        /// <param name="dtLast"></param>
        /// <param name="dtThis"></param>
        /// <param name="abs">是否取绝对值</param>
        /// <returns></returns>
        public static long IntervalTicks(this DateTime dtLast, DateTime dtThis, bool abs = false)
        {
            return (abs ? Math.Max(0, (dtLast - dtThis).Ticks) : (dtLast - dtThis).Ticks);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="hh"></param>
        /// <param name="mm"></param>
        /// <param name="ss"></param>
        /// <returns></returns>
        public static DateTime AddHoursMinutesSeconds(this DateTime dt, double hh, double mm, double ss)
        {
            return (dt.AddHours(hh).AddMinutes(mm).AddSeconds(ss));
        }
        /// <summary>
        /// 获取指定日期，在为一年中为第几周
        /// </summary>
        /// <param name="dt">指定时间</param>
        /// <reutrn>返回第几周</reutrn>
        public static int WeekOfYear(this DateTime dt)
        {
            GregorianCalendar gc = new GregorianCalendar();
            int weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
            return weekOfYear;
        }
        /// <summary>
        /// 判断是否是同一天
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <returns></returns>
        public static bool SameDay(this DateTime dt1, DateTime dt2)
        {
            return dt1.Date.Equals(dt2.Date);
        }
        /// <summary>
        /// 判断是否是同天同一点钟
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <returns></returns>
        public static bool SameDayHour(this DateTime dt1, DateTime dt2)
        {
            return (dt1.SameDay(dt2) && dt1.Hour == dt2.Hour);
        }
        /// <summary>
        /// 判断是否是同天同一点钟且在某一点钟
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <returns></returns>
        public static bool SameDayHourMinute(this DateTime dt1, DateTime dt2)
        {
            return (dt1.SameDay(dt2) && dt1.Hour == dt2.Hour && dt1.Minute == dt2.Minute);
        }
        /// <summary>
        /// 判断是否是在同一周
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <param name="周日为最后一天"></param>
        /// <returns></returns>
        public static bool SameWeek(this DateTime dt1, DateTime dt2, bool 周日为最后一天 = true)
        {
            DateTime temp1 = dt1.GetWeekStartDateTime(周日为最后一天);
            DateTime temp2 = dt2.GetWeekStartDateTime(周日为最后一天);
            return (temp1 == temp2);
        }
        /// <summary>
        /// 获取每周的第一天开始时间
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="周日为最后一天"></param>
        /// <returns></returns>
        public static DateTime GetWeekStartDateTime(this DateTime dt, bool 周日为最后一天 = true)
        {
            int 减少天数 = - (int)dt.DayOfWeek;
            if (周日为最后一天)
            {
                减少天数 += 1;
                if (dt.DayOfWeek == DayOfWeek.Sunday)
                {
                    减少天数 -= 7;
                }
            }
            return dt.AddDays(减少天数).Date;
        }
        /// <summary>
        /// 获取每周的截止时间
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="周日为最后一天"></param>
        /// <returns></returns>
        public static DateTime GetWeekEndDateTime(this DateTime dt, bool 周日为最后一天 = true)
        {
            return dt.GetWeekStartDateTime(周日为最后一天).AddDays(7).AddSeconds(-1);
        }
        /// <summary>
        /// 判断是否是在同一周且同一天
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <param name="周日为最后一天"></param>
        /// <returns></returns>
        public static bool SameWeekDay(this DateTime dt1, DateTime dt2, bool 周日为最后一天 = true)
        {
            return (dt1.SameWeek(dt2, 周日为最后一天) && dt1.DayOfWeek == dt2.DayOfWeek);
        }
        /// <summary>
        /// 判断是否是在同一月
        /// </summary>
        /// <param name="dt1"></param>
        /// <param name="dt2"></param>
        /// <returns></returns>
        public static bool SameMonth(this DateTime dt1, DateTime dt2)
        {
            return (dt1.Year == dt2.Year && dt1.Month == dt2.Month);
        }
        /// <summary>
        /// 获取每月的开始时间
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime GetMonthStartDateTime(this DateTime dt)
        {
            return dt.AddDays(1 - dt.Day).Date;
        }
        /// <summary>
        /// 获取每月的截止时间
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime GetMonthEndDateTime(this DateTime dt)
        {
            return dt.AddDays(1 - dt.Day).Date.AddMonths(1);
        }
        /// <summary>
        /// 获取当前时间到下次日零点更新时间的间隔
        /// </summary>
        /// <returns></returns>
        public static TimeSpan GetCooldownToDayEnd()
        {
            var dtNow = DateTime.Now;
            return dtNow.Date.AddDays(1) - dtNow;
        }
        /// <summary>
        /// 获取当前时间到下次周零点更新时间的间隔
        /// </summary>
        /// <returns></returns>
        public static TimeSpan GetCooldownToWeekEnd()
        {
            var dtNow = DateTime.Now;
            return dtNow.GetWeekEndDateTime(true) - dtNow;
        }
        /// <summary>
        /// 获取当前时间到下次月零点更新时间的间隔
        /// </summary>
        /// <returns></returns>
        public static TimeSpan GetCooldownToMonthEnd()
        {
            var dtNow = DateTime.Now;
            return dtNow.GetMonthEndDateTime() - dtNow;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="other"></param>
        /// <returns></returns>
        public static TimeSpan Min(this TimeSpan source, TimeSpan other)
        {
            return source.Ticks > other.Ticks ? other : source;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="other"></param>
        /// <returns></returns>
        public static TimeSpan Max(this TimeSpan source, TimeSpan other)
        {
            return source.Ticks < other.Ticks ? other : source;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticks"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this long ticks)
        {
            return new DateTime(ticks);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ticks"></param>
        /// <returns></returns>
        public static TimeSpan ToTimeSpan(this long ticks)
        {
            return new TimeSpan(ticks);
        }


    }
}
